// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`abnormals.js 1`] = `
/* @flow */

/* This test documents an issue we used to have with merging the environment of
 * the try block and the catch block. The error variable, when inspected and in
 * the presence of an abnormal, would sometimes kind of leak. It would hit an
 * abnormal. It was weird.
 */
function foo() {
  try {
  } catch(error) {
    if (error.foo === 4) {
      throw error;
    }
  }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

/* This test documents an issue we used to have with merging the environment of
 * the try block and the catch block. The error variable, when inspected and in
 * the presence of an abnormal, would sometimes kind of leak. It would hit an
 * abnormal. It was weird.
 */
function foo() {
  try {
  } catch (error) {
    if (error.foo === 4) {
      throw error;
    }
  }
}

`;

exports[`init.js 1`] = `
/***
 * test initialization tracking of hoisted stuff
 * @flow
 */

// for illustrative purposes only - Flow considers a throw possible
// anywhere within a block
function might_throw() {}

// local use of annotated var within try is ok
function f() {
  try {
    var x:number = 0;
    var y:number = x;
  } catch (e) {
  }
}

// and within catch
function f() {
  try {
  } catch (e) {
    var x:number = 0;
    var y:number = x;
  }
}

// but not across try/catch
function f() {
  try {
    might_throw();
    var x:number = 0;
  } catch (e) {
    var y:number = x; // error
  }
}

// or try/finally
function f() {
  try {
    might_throw();
    var x:number = 0;
  } finally {
    var y:number = x; // error
  }
}

// or catch/finally
function f() {
  try {
  } catch (e) {
    var x:number = 0;
  } finally {
    var y:number = x; // error
  }
}

// or try/catch/finally if init doesn't dominate
function f() {
  try {
    var x:number = 0;
  } catch (e) {
    might_throw();
    var x:number = 0;
  } finally {
    var y:number = x; // error
  }
}

// post-use ok because init dominates here
function f() {
  try {
    var x:number = 0;
  } catch (e) {
    might_throw();  // ...but if so, suffix is not reached
    var x:number = 0;
  }
  var y:number = x;
}

// and here
function f() {
  try {
  } catch (e) {
  } finally {
    might_throw();  // ...but if so, suffix is not reached
    var x:number = 0;
  }
  var y:number = x;
}

// and here
function f() {
  try {
    var x:number;
  } catch (e) {
  } finally {
    might_throw();  // ...but if so, suffix is not reached
    x = 0;
  }
  var y:number = x;
}

// and here, thank you JS for the wonder that is hoisting
function f() {
  try {
  } catch (e) {
    var x:number;
  } finally {
    might_throw();  // ...but if so, suffix is not reached
    x = 0;
  }
  var y:number = x;
}

// error if used prior to init
function f() {
  var y:number = x; // error
  try {
    var x:number = 0;
  } catch (e) {
  }
}

// another non-dominated post
function f() {
  try {
    var x:number = 0;
  } catch (e) {
  }
  var y:number = x; // error
}

// ditto
function f() {
  try {
  } catch (e) {
    var x:number = 0;
  }
  var y:number = x; // error
}

// ditto
function f(b) {
  try {
    var x:number;
    if (b) {
      throw new Error();
    }
    x = 0;
  } catch (e) {
  }
  var y:number = x; // error
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/***
 * test initialization tracking of hoisted stuff
 * @flow
 */

// for illustrative purposes only - Flow considers a throw possible
// anywhere within a block
function might_throw() {}

// local use of annotated var within try is ok
function f() {
  try {
    var x: number = 0;
    var y: number = x;
  } catch (e) {}
}

// and within catch
function f() {
  try {
  } catch (e) {
    var x: number = 0;
    var y: number = x;
  }
}

// but not across try/catch
function f() {
  try {
    might_throw();
    var x: number = 0;
  } catch (e) {
    var y: number = x; // error
  }
}

// or try/finally
function f() {
  try {
    might_throw();
    var x: number = 0;
  } finally {
    var y: number = x; // error
  }
}

// or catch/finally
function f() {
  try {
  } catch (e) {
    var x: number = 0;
  } finally {
    var y: number = x; // error
  }
}

// or try/catch/finally if init doesn't dominate
function f() {
  try {
    var x: number = 0;
  } catch (e) {
    might_throw();
    var x: number = 0;
  } finally {
    var y: number = x; // error
  }
}

// post-use ok because init dominates here
function f() {
  try {
    var x: number = 0;
  } catch (e) {
    might_throw(); // ...but if so, suffix is not reached
    var x: number = 0;
  }
  var y: number = x;
}

// and here
function f() {
  try {
  } catch (e) {
  } finally {
    might_throw(); // ...but if so, suffix is not reached
    var x: number = 0;
  }
  var y: number = x;
}

// and here
function f() {
  try {
    var x: number;
  } catch (e) {
  } finally {
    might_throw(); // ...but if so, suffix is not reached
    x = 0;
  }
  var y: number = x;
}

// and here, thank you JS for the wonder that is hoisting
function f() {
  try {
  } catch (e) {
    var x: number;
  } finally {
    might_throw(); // ...but if so, suffix is not reached
    x = 0;
  }
  var y: number = x;
}

// error if used prior to init
function f() {
  var y: number = x; // error
  try {
    var x: number = 0;
  } catch (e) {}
}

// another non-dominated post
function f() {
  try {
    var x: number = 0;
  } catch (e) {}
  var y: number = x; // error
}

// ditto
function f() {
  try {
  } catch (e) {
    var x: number = 0;
  }
  var y: number = x; // error
}

// ditto
function f(b) {
  try {
    var x: number;
    if (b) {
      throw new Error();
    }
    x = 0;
  } catch (e) {}
  var y: number = x; // error
}

`;

exports[`return.js 1`] = `
/**
 * @flow
 */

function foo(x: ?number): string {
    try {
    } catch (e) {
        return 'bar';
    }
    console.log();
    return 'foo';
}

function bar(): string {
  try {
    return 'foo';
  } catch (e) {
    return 'bar';
  }
}

function baz(): string {
  try {
    throw new Error("foo");
  } catch (e) {
    return "foo";
  }
  return "bar"; // unreachable
}

function qux(): string {
  try {
    throw new Error("foo");
  } catch (e) {
  }
  console.log();
  return 'bar';
}

function quux(): string {
  try {
    return qux();
  } catch (e) {
  }
  return 'bar';
}

function bliffl(): string {
  try {
    throw new Error("foo");
  } catch (e) {
    return "foo";
  } finally {
    return "bar";
  }
}

function corge(): string {
  try {
    return 'foo';
  } catch (e) {
    throw new Error('bar');
  }
  bar(); // unreachable
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * @flow
 */

function foo(x: ?number): string {
  try {
  } catch (e) {
    return "bar";
  }
  console.log();
  return "foo";
}

function bar(): string {
  try {
    return "foo";
  } catch (e) {
    return "bar";
  }
}

function baz(): string {
  try {
    throw new Error("foo");
  } catch (e) {
    return "foo";
  }
  return "bar"; // unreachable
}

function qux(): string {
  try {
    throw new Error("foo");
  } catch (e) {}
  console.log();
  return "bar";
}

function quux(): string {
  try {
    return qux();
  } catch (e) {}
  return "bar";
}

function bliffl(): string {
  try {
    throw new Error("foo");
  } catch (e) {
    return "foo";
  } finally {
    return "bar";
  }
}

function corge(): string {
  try {
    return "foo";
  } catch (e) {
    throw new Error("bar");
  }
  bar(); // unreachable
}

`;

exports[`test.js 1`] = `
/***
 * test env state tracking thru try/catch/finally
 * @flow
 */

function foo() {
    var x = 0;
    var y;
    try {
        x = "";
    } catch(e) {
        x = false;
        throw -1;
    } finally {
        y = {};
    }
    // here via [try; finally] only.
    x(); // string ~/> function call (no num or bool error)
    y(); // object ~/> function call (no uninitialized error)
}

function bar(response) {
    var payload;
    try {
        payload = JSON.parse(response);
    } catch (e) {
        throw new Error('...');
    }
    // here via [try] only.
    if (payload.error) {    // ok
        // ...
    }
}

function qux() {
    var x = 5;
    try {
        throw -1;
    } finally {
    }
    x(); // unreachable
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/***
 * test env state tracking thru try/catch/finally
 * @flow
 */

function foo() {
  var x = 0;
  var y;
  try {
    x = "";
  } catch (e) {
    x = false;
    throw -1;
  } finally {
    y = {};
  }
  // here via [try; finally] only.
  x(); // string ~/> function call (no num or bool error)
  y(); // object ~/> function call (no uninitialized error)
}

function bar(response) {
  var payload;
  try {
    payload = JSON.parse(response);
  } catch (e) {
    throw new Error("...");
  }
  // here via [try] only.
  if (payload.error) {
    // ok
    // ...
  }
}

function qux() {
  var x = 5;
  try {
    throw -1;
  } finally {
  }
  x(); // unreachable
}

`;
